/***
 * Core.js
 * @author Bodhi
 * @date 2016\01\11
 * @desc interface json data tree adapter.
 *
 */
(function ($, Node, Tree, DataSourceTree, Utils) {
	var funcTreeBind,       //bind data to tree plugin.
		buildCommonTree,      //build tree
		buildHsfTree,
		funcAdapt,
		visitNode,
		dataSourceRes = {},
		hasOwnProperty = Object.prototype.hasOwnProperty;

	funcTreeBind = function (res) {
		if ($.isPlainObject(res)) {
			var treeDataSource = new DataSourceTree({data: res});
			$('#nav_tree').ace_tree({
				dataSource: treeDataSource,
				loadingHTML: '<div class="tree-loading"><i class="icon-refresh icon-spin blue"></i></div>',
				'open-icon': 'icon-folder-open',
				'close-icon': 'icon-folder-close',
				multiSelect: false,
				'selectable': false,
				'selected-icon': null,
				'unselected-icon': null
			});
		}
	};

	/***
	 * build the tree from json file , the json file format is like json/example.json
	 * @param parent
	 * @param json
	 */
	buildCommonTree = function (parent, json) {
		(function f(parent, json) {
			var childs = json.childs;
			for (var i = 0; i < childs.length; i++) {
				var item = childs[i],
					node = new Node({
						id: item.id,
						title: item.title,
						locale: item.locale,
						description: item.description,
						icon: item.icon
					});

				parent.append(node);
				node.height = parent.height + 1;

				if (item.childs !== undefined && item.childs !== 0) {
					f(node, {childs: item.childs});
				}
			}
		}(parent, json));
	};

	/***
	 * build the tree from json file , the json file format is like json/tree.json
	 * @param parent
	 * @param json
	 */
	buildHsfTree = function (parent, json) {
		(function f(parent, json) {
			var it = new Utils.Iterator(json);

			do {
				var current = it.current(),
					value = current.value,
					owns = (value['owns'] || []),
					node = new Node();

				node.data = {
					title: value.title,
					icon: value.icon || '',
					description: value.description,
					locale: current.key
				};

				parent.append(node);
				node.height = parent.height + 1;

				if (owns && owns.length > 0) {
					for (var i = 0; i < owns.length; i++) {
						var item = owns[i];
						f(node, item);
					}
				}
			} while (it.next() !== undefined);
		}(parent, json));

		return parent;
	};


	/**
	 * 按照层次遍历访问每个节点并对该节点进行操作。 !important
	 * @param node
	 */
	visitNode = function (node) {
		var type = node.childs && node.childs.length !== 0 ? 'folder' : 'item',
			data = node.data;

		if (node.height === 0) {
			dataSourceRes = {};
			return;
		}

		(function (time, obj, parentsData) {
			var _obj;

			_obj = Utils.deeperObj(obj, function () {
				var pop = parentsData.pop(),
					locale = pop !== undefined && hasOwnProperty.call(pop, 'locale') && pop.locale;

				return locale + '.additionalParameters.children';
			}, time);

			_obj[data.locale] = {name: data.title, type: type, icon: data.icon || ''};

			return obj;
		}(node.height - 1, dataSourceRes, node.parents()));
	};

	/***
	 * list of action.
	 * @param json
	 */
	funcAdapt = function (json) {
		var root;

		if (!hasOwnProperty.call(json, 'title')) {
			root = new Node();
			root.height = 0;
		}

		new Tree(buildHsfTree(root, json)).levelPrint(visitNode);
		funcTreeBind(dataSourceRes);
	};


	/**
	 * get data from server , pass an callback as parameter that deal with data.
	 *
	 */
	(function (callback) {
		var self = this;
		Utils.lazyAjax('json/data_tree.json', function (json) {
			if ($.isFunction(callback) && json && json.data) {
				callback.call(self, json.data);
			} else {
				throw new TypeError('please check json data.');
			}
		});
	}(funcAdapt));
}(jQuery, Node, Tree, DataSourceTree, Utils));

